package com.example.blogdemo1.common.utils;

/*
 * @author zzr
 * @date: 2025/10/05  20:43
 * @description:
 */

import com.example.blogdemo1.common.constants.Constants;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;

import java.lang.module.Configuration;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JWTUtils {

    // 过期时间
    private static final long JWT_EXPIRATION = 60*60*1000;
    // 密钥 一段 Base64 编码的密钥字符串
    private static final String secretStr = "Le++o8NQWVXWo3+SJtAtnjBW9iA0OvPL0c0mMrol2fU=";

    // 生成安全密钥
    // 将 Base64 编码的密钥解码，生成符合 HMAC-SHA 算法要求的key对象（后续用它给 JWT 前面，防止令牌被篡改）
    private static final Key key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretStr));

    /**
     * 生成 token
     */
    public static String genJwtToken(Map<String,Object> claim) {
        String token = Jwts.builder()
                .setClaims(claim) // 将自定义信息放入JWT载荷中
                .setExpiration(new Date(System.currentTimeMillis()+JWT_EXPIRATION))
                .signWith(key) // 对 JWT 进行签名
                .compact();

        return token;
    }

    /**
     * 校验 token
     * Claims 为 null 表示校验失败
     */
    public static Claims parseToken(String token) {
        // 创建 JWT 解析器构建起，并设置签名密钥
        JwtParser build = Jwts.parserBuilder().setSigningKey(key).build();
        Claims claims = null;
        try {
           // 解析 JWT 令牌
            claims = build.parseClaimsJws(token).getBody();
        } catch (Exception e) {
            log.error("解析 token 失败,token:{}",token);
            return null;
        }
        return claims;
    }

    /**
     * 从 token 中获取用户 ID
     */
    public static Integer getUserIdFromToken(String token) {
        Claims claims = JWTUtils.parseToken(token);
        if (claims != null) {
            Map<String,Object> userInfo = new HashMap<>(claims);
            return (Integer) userInfo.get("id");
        }
        return null;

    }

    public static Integer getIdByToken(String token) {
        Claims claims = parseToken(token);
        if (claims != null) {
            Integer userId = (Integer) claims.get(Constants.TOKEN_ID);
            if (userId > 0) {
                return userId;
            }
        }
        return null;

    }
}
